package uk.org.landeg.euler.problems;

import java.awt.Point;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import uk.org.landeg.euler.problems.framework.AbstractProblem;
import uk.org.landeg.euler.problems.framework.ProblemLauncher;

public class Problem011 extends AbstractProblem{
	public static void main(String[] args) {
		ProblemLauncher launcher = new ProblemLauncher(new Problem011());
		launcher.solve();
	}
	
	@Override
	public String getDescription() {
		return "What is the greatest product of four adjacent numbers in any direction";
	}

	@Override
	public Integer getProblemNumber() {
		// TODO Auto-generated method stub
		return 11;
	}

	
	int transforms[][] = {
			{0,1},
			{1,1},
			{1,0},
			{1,-1},
			{1,0}
	};
	
	int grid[][] = new int[20][20];
	
	private void parseNumbers () throws NumberFormatException, IOException {
		int x = 0; int y = 0;
			BufferedReader reader = new BufferedReader(new FileReader("data/problem011.txt"));
			Pattern p = Pattern.compile("(\\d){2}");
			Matcher m;
			String line;
			while ((line = reader.readLine()) != null) {
				m = p.matcher(line);
				x = 0;
				while (m.find()) {
					grid[x++][y] = Integer.parseInt(m.group());
				}
				y++;
			}
			
			for (int[] nums : grid) {
				notes.add("Read numbers : " + Arrays.toString(nums));
			}
	}

	private Long getTotalWithTransform (Point start, int[]transform) {
		Point current = new Point (start);
		long product = 1;
		for (int step = 0 ; step < 4 ; step++) {
			try {
				if (grid[current.x][current.y] == 0) {
					return 0L;
				}
				product *= grid[current.x][current.y];
				current.translate(transform[0], transform[1]);
			} catch (IndexOutOfBoundsException e) {
				return 0L;
			}
		}
		return product;
	}
	
	@Override
	public Object solve() {
		notes.add("Parse numbers");
		Object ret = null;
		Point startLoc = new Point(0,0);
		long thisProd, maxProd = 0;
		try {
			parseNumbers();
			for (int x = 0; x < 20 ; x++) {
				for (int y = 0 ; y < 20 ; y++) {
					startLoc.setLocation(x, y);
					for (int[] transform : transforms) {
						thisProd = getTotalWithTransform(startLoc, transform);
						if (thisProd > maxProd) {
							notes.add("new Maxima found : " + thisProd);
							maxProd = thisProd;
							ret = maxProd;
						}
					}
				}
			}
		} catch (Exception e) {
			return ret;
		}
		return ret;
	}

}
